<?php

/*
 * Manager/PlanningManager.php
 */

namespace RHX\Model\Manager;

use Zend\Db\Adapter\Adapter;
use RHX\Model\Object\PlanningSemaine;
use RHX\Model\Table\PlanningSemaineTable;
use RHX\Model\Object\EmployeTemplate;
use RHX\Model\Table\EmployeTemplateTable;
use RHX\Model\Object\Employe;
use RHX\Model\Table\EmployeTable;
use RHX\Model\Object\Semaine;
use RHX\Model\Table\SemaineTable;
use RHX\Model\Object\Periode;
use RHX\Model\Table\PeriodeTable;
use RHX\Model\Object\Site;
use RHX\Model\Table\SiteTable;
use RHX\Model\Object\CodeActivite;
use RHX\Model\Table\CodeActiviteTable;
use RHX\Model\Object\XData;
use RHX\Model\Object\XCalculator;
use RHX\Model\Object\XRules;
use RHX\Model\Manager\TemplateManager;
use RHX\Helper\Day;
use RHX\Helper\RHDateTime;

class PlanningManager {

    private $adapter = null;

    /**
     * Constructeur
     * 
     * @param \Zend\Db\Adapter\Adapter $adapter
     */
    public function __construct(Adapter $adapter) {
	$this->adapter = $adapter;
    }

    /**
     * Adapteur de base de données
     * 
     * @return Adapter
     */
    public function getAdapter() {
	return $this->adapter;
    }

    public function edit($periodeId, $semaineId, $site) {
	// tables
	$tablePeriode	 = new PeriodeTable($this->getAdapter());
	$tableSemaine	 = new SemaineTable($this->getAdapter());
	$tableSite	 = new SiteTable($this->getAdapter());
	$tablePlanning	 = new PlanningSemaineTable($this->getAdapter());
    }

    /**
     * Résumé du jour
     * 
     * @param \RHX\Model\Object\PlanningSemaine $planning
     * @param \RHX\Helper\Day $day
     * @return \RHX\Helper\Day
     */
    public function summaryDay(PlanningSemaine $planning, $day = 'lundi') {
	$day = new Day($planning, $day);

	return $day;
    }

    /**
     * Résumé de la semaine
     * 
     * @param \RHX\Model\Object\PlanningSemaine $planning
     * @return \RHX\Helper\Day
     */
    public function summaryWeek(PlanningSemaine $planning) {
	$dayName	 = array('lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche');
	$summaries	 = array();
	foreach ($dayName as $day) {
	    $summaries[$day] = new Day($planning, $day);
	}
	return $summaries;
    }

    /**
     * Résumé de toute la période
     * 
     * @param \RHX\Model\Object\Employe $employe
     * @param \RHX\Model\Object\Periode $periode
     * @return array
     */
    public function summaryPeriod(Employe $employe, Periode $periode) {
	$plannings	 = $this->getEmployePlanningByPeriode($employe->matricule, $periode);
//	\Zend\Debug\Debug::dump($plannings);
	$summaries	 = array();
	foreach ($plannings as $planning) {
	    $summaries[] = $this->summaryWeek($planning);
	}
	return $summaries;
    }

    /**
     * Récupérer les plannings de l'employé sur une période donnée
     * 
     * @param int $matricule
     * @param \RHX\Model\Object\Periode $periode
     * @return \Zend\Db\ResultSet\ResultSet
     */
    public function getEmployePlanningByPeriode($matricule, Periode $periode) {
	$table		 = new PlanningSemaineTable($this->getAdapter());
	$plannings	 = $table->getPlanningsByDateRange($matricule, $periode->debut, $periode->fin);
	return $plannings;
    }

    /**
     * Planning semaine
     * 
     * @param int $planningId
     * @return PlanningSemaine
     */
    public function getPlanning($planningId) {
	$tablePlanning = new PlanningSemaineTable($this->getAdapter());
	return $tablePlanning->get($planningId);
    }

    /**
     * Employé
     * 
     * @param int $matricule
     * @return Employe
     */
    public function getEmploye($matricule) {
	$tableEmploye = new EmployeTable($this->getAdapter());
	return $tableEmploye->get($matricule);
    }

    /**
     * Periode
     * 
     * @param string $date
     * @return \RHX\Model\Object\Periode
     */
    public function getPeriode($date) {
	$tablePeriode = new PeriodeTable($this->getAdapter());
	return new Periode($tablePeriode->getPeriodeByDate($date));
    }

    /**
     * Statistique de la semaine
     * 
     * @param \RHX\Model\Object\PlanningSemaine $planning
     * @return array
     */
    public function getWeekStat(PlanningSemaine $planning) {
	$statCode	 = array();
	$statHeure	 = array();
	$week		 = $this->summaryWeek($planning);
	foreach ($week as $day) {
	    if (!isset($statCode[$day->code])) {
		$statCode[$day->code] = 0;
	    }
	    $statCode[$day->code] ++;
	    if (!isset($statHeure[$day->code])) {
		$statHeure[$day->code] = new \RHX\Helper\RHDateTime();
		$statHeure[$day->code]->setTime();
	    }
	    $statHeure[$day->code]->addHours($day->getDiff(false), false);
	}
	return array(
	    'codes'	 => $statCode,
	    'heures' => $statHeure,
	    'week'	 => $week,
	);
    }

    /**
     * Code activité
     * 
     * @param int $code
     * @return CodeActivite
     */
    public function getCode($code) {
	$tableCode = new CodeActiviteTable($this->getAdapter());
	try {
	    return $tableCode->get($code);
	}
	catch (\Exception $ex) {
	    return null;
	}
    }

    /**
     * Codec des codes
     * 
     * @return array
     */
    public function getCodec() {
	$tableCode	 = new CodeActiviteTable($this->getAdapter());
	$codes		 = $tableCode->getAll('id ASC', true);
	$codec		 = array();
	foreach ($codes as $c) {
	    $codec[(int) $c->id] = $c->code;
	}
	return $codec;
    }

    /**
     * Effacer une semaine d'un planning
     * 
     * @param int $ppId
     * @param int $siteId
     * @return array
     */
    public function delete($ppId, $siteId) {
	$planningPeriode = $this->getPlanningPeriode($ppId);
	$semaine	 = $this->getSemaine($planningPeriode->semaine_id);
	$employes	 = $this->getEmployesBySite($siteId, true);
	$resultSemaine	 = $this->deleteSemaine($employes, $semaine->lundi, $semaine->dimanche);
	$resultTemplate	 = $this->deleteTemplate($planningPeriode->template);
	$resultPeriode	 = $this->deletePlanningPeriode($ppId);
	return array(
	    'semaine'	 => $resultSemaine,
	    'template'	 => $resultTemplate,
	    'periode'	 => $resultPeriode,
	);
    }

    /**
     * Planning Periode
     * 
     * @param int $ppId
     * @return \RHX\Model\Object\PlanningPeriode|NULL
     */
    public function getPlanningPeriode($ppId) {
	$tablePP = new \RHX\Model\Table\PlanningPeriodeTable($this->getAdapter());
	try {
	    return $tablePP->get($ppId);
	}
	catch (\Exception $ex) {
	    return null;
	}
    }

    /**
     * Semaine
     * 
     * @param int $semaineId
     * @return Semaine
     */
    public function getSemaine($semaineId) {
	$tableSemaine = new SemaineTable($this->getAdapter());
	try {
	    return $tableSemaine->get($semaineId);
	}
	catch (Exception $ex) {
	    return null;
	}
    }

    /**
     * Effacer semaine
     * 
     * @param array $employeList
     * @param string $lundi
     * @param string $dimanche
     * @return array
     */
    public function deleteSemaine($employeList, $lundi, $dimanche) {
	$plannings	 = $this->getPlannings($employeList, $lundi, $dimanche);
	$arrayId	 = $this->getArrayId($plannings);
	$tablePlanning	 = new PlanningSemaineTable($this->getAdapter());
	$where		 = new \Zend\Db\Sql\Where();
	$where->in('id', $arrayId);
	$nb		 = $tablePlanning->delete($where);
	return array(
	    'nb'		 => $nb,
	    'plannings'	 => $plannings,
	    'id'		 => $arrayId,
	);
    }

    /**
     * Liste des employés d'un site
     * 
     * @param int $siteId
     * @param boolean $toArray
     * @return \Zend\Db\ResultSet\ResultSet|Array
     */
    public function getEmployesBySite($siteId, $toArray = false) {
	$tableEmploye	 = new EmployeTable($this->getAdapter());
	$employeList	 = $tableEmploye->getEmployesBySite($siteId);
	if ($toArray) {
	    $employes = array();
	    foreach ($employeList as $e) {
		$employes[] = $e->matricule;
	    }
	}
	return $employes;
    }

    /**
     * Planning Semaine
     * 
     * @param array $employeList
     * @param string $lundi
     * @param string $dimanche
     * @return PlanningSemaine
     */
    public function getPlannings($employeList, $lundi, $dimanche) {
	$tablePlanning	 = new PlanningSemaineTable($this->getAdapter());
	$planningList	 = $tablePlanning->select(function(\Zend\Db\Sql\Select $select)use($employeList, $lundi, $dimanche) {
	    $where = new \Zend\Db\Sql\Where();
	    $where->between('lundi', $lundi, $dimanche);
	    $where->in('matricule', $employeList);
	    $select->where($where);
	});
	$plannings = array();
	foreach ($planningList as $planning) {
	    $plannings[] = $planning;
	}
	return $plannings;
    }

    /**
     * Récupérer les identifiants
     * 
     * @param mixed $array
     * @return array
     */
    public function getArrayId($array) {
	$arrayId = array();
	foreach ($array as $elt) {
	    $arrayId[] = $elt->id;
	}
	return $arrayId;
    }

    /**
     * Templates
     * 
     * @param type $templateId
     * @return EmployeTemplate
     */
    public function getTemplates($templateId) {
	$tableEmployeTemplate	 = new EmployeTemplateTable($this->getAdapter());
	$templateList		 = $tableEmployeTemplate->getTemplates($templateId);
	$templates		 = array();
	foreach ($templateList as $t) {
	    $templates[] = $t;
	}
	return $templates;
    }

    /**
     * Effacer Template
     * 
     * @param int $templateId
     * @return array
     */
    public function deleteTemplate($templateId) {
	$tableTemplate		 = new \RHX\Model\Table\PlanningTemplateTable($this->getAdapter());
	$tableEmployeTemplate	 = new EmployeTemplateTable($this->getAdapter());
	$template		 = $tableTemplate->getTemplate($templateId);
	$templates		 = $this->getTemplates($templateId);
	$arrayId		 = $this->getArrayId($templates);
	$where			 = new \Zend\Db\Sql\Where();
	$where->in('id', $arrayId);
	$nb			 = $tableEmployeTemplate->delete($where);

	$tableTemplate->erase($templateId);

	return array(
	    'nb'		 => $nb,
	    'template'	 => $template,
	    'templates'	 => $templates,
	);
    }

    /**
     * Effacer Planning Période
     * 
     * @param int $ppId
     * @return array
     */
    public function deletePlanningPeriode($ppId) {
	$tablePP = new \RHX\Model\Table\PlanningPeriodeTable($this->getAdapter());
	$pp	 = $tablePP->get($ppId);
	$nb	 = $tablePP->delete(array('id' => $ppId));
	return array(
	    'nb'			 => $nb,
	    'planningPeriode'	 => $pp,
	);
    }

    /**
     * Insertion d'un nouveau Ideal
     * 
     * @param \Zend\Stdlib\Parameters $post
     * @return \Zend\View\Model\JsonModel
     */
    public function insertIdeal($post) {
	$ideal		 = new \RHX\Model\Object\Ideal();
	$ideal->jour	 = $post->date;
	$ideal->site	 = $post->site;
	$ideal->nb	 = $post->nb;
	$tableIdeal	 = new \RHX\Model\Table\IdealTable($this->getAdapter());
	$ideal->id	 = $tableIdeal->save($ideal);
	return new \Zend\View\Model\JsonModel(array('ideal' => $ideal));
    }

    /**
     * Mise à jour de l'ideal
     * 
     * @param \Zend\Stdlib\Parameters $post
     * @return \Zend\View\Model\JsonModel
     */
    public function updateIdeal($post) {
	$tableIdeal	 = new \RHX\Model\Table\IdealTable($this->getAdapter());
	$ideal		 = $tableIdeal->get($post->id);
	$ideal->nb	 = $post->nb;
	$tableIdeal->save($ideal);
	return new \Zend\View\Model\JsonModel(array('ideal' => $ideal));
    }

    /* Mettre à jour tous les planning semaine d'un employé d'un site  par rapport à sa date d'entrée et de sortie
     * @param int matricule 
     */

    public function updatePlanningSemaines($matricule, $siteId) {
        // manager
        $empManager = new \RHX\Model\Manager\EmployeManager($this->getAdapter());

	//TABLES    
	$planningSemaineTable	 = new \RHX\Model\Table\PlanningSemaineTable($this->getAdapter());
	$periodeSemaineTable	 = new \RHX\Model\Table\PeriodeSemaineTable($this->getAdapter());
	$periodeTable		 = new \RHX\Model\Table\PeriodeTable($this->getAdapter());
	$employeTable		 = new \RHX\Model\Table\EmployeTable($this->getAdapter());
	$employeTemplateTable	 = new \RHX\Model\Table\EmployeTemplateTable($this->getAdapter());

	//vue
	$planningListView = new \RHX\Model\View\PSPlanningView($this->getAdapter());

	// calculateur
	$calculator = new \RHX\Model\Object\XCalculator($this->getAdapter());

	//$matricule = 32; // id de test
	// periodes 
	$periodes = $periodeTable->getAll('id DESC');

	//l'employé
	$thisEmp = $matricule ? $employeTable->get($matricule) : null;

	$hasDateDepart	 = $thisEmp->contrat_fin != null && $thisEmp->contrat_fin !== '' && $thisEmp->contrat_fin !== '0000-00-00';

	////echo 'date contrat : [' . $thisEmp->contrat_debut . ' :' .  $thisEmp->contrat_fin . '] <br>' ;
	foreach ($periodes as $periode) {
	    // Liste des Semaines d'une Période
	    $semaineList = $periodeSemaineTable->getSemainesByPeriode($periode->id, 'id desc');

	    print('-- ' . $periode->libelle . ' -------------------------------------- [' . $periode->debut . ' : ' . $periode->fin . ' ] ---------- <br>');

            var_dump($thisEmp->contrat_debut . ' << ');
	    if ($empManager->chevauchePeriodeEmploye($thisEmp->matricule, $periode->id)) { // si periode contient un des dates du contrat : MAJ les lignes planning semaine
		print (" periode includes contrat date!<br>");
		foreach ($semaineList as $semaine) {
                    $dayWks			 = array('Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche');
		    $lundi		 = $semaine->lundi;
		    //$planSemEmploye	 = $planningSemaineTable->getByEmploye($matricule, $lundi);

		    print('semaine ' . $semaine->id . '[  lundi : ' . $lundi . '] | ');
		    // 'planning type' & 'planning type employe' de l'employe
		    $psInView	 = $planningListView->getOne($periode->id, $semaine->id, $siteId);
                    $semaineHasPS = (boolean)$psInView->template;
                    
                    //recupération template
                    if($semaineHasPS){
                        $templateId   = (int) $psInView->template;
                        $employeTemplate	 = $employeTemplateTable->getEmployeTemplate($matricule, $templateId);
                    }
                    
                    // MAJ PS
                    if ($semaineHasPS){
                        echo (" >  SEM HAS PS ");
                        $planSemEmploye	 = $planningSemaineTable->getByEmploye($matricule, $lundi);
                        print($planSemEmploye ? 'ps ' . $planSemEmploye->id . ' ' : ' ps vide '); // != null? $planSemEmploye->id : 'NOT') ; 
                        
                        if ($planSemEmploye) {
                            echo (" >  EMP HAS PS ");
                            $this->updatePlanningSemaine($matricule, $planSemEmploye, $templateId);
                        }
                        else{
                            ///// BEGIN employe has not ps
                            echo (" >  EMP HASNT PS (creating) ");
                            $planning = new \RHX\Model\Object\PlanningSemaine($planningSemaineTable->getAdapter());
                            $this->createPlanningSemaine($matricule, $planning, $templateId, $semaine->id);                            
                            ///// END employe has not ps
                        }
                    }
		    else {
                        //nothing to do
			echo (" > SEM HASNT PS ");
		    }
		    print('<br>');

		    // update prorata planning semaine
                    if($semaineHasPS){
                        // reload planning 
                        $planSemEmploye = $planningSemaineTable->getByEmploye($matricule, $lundi);
                        
                        //retrieve PT
                        $templateId     = (int) $psInView->template;
                        $employeTpl     = $employeTemplateTable->getEmployeTemplate($matricule, $templateId);
                        
                        if ($planSemEmploye) {
                            foreach ($dayWks as $daywk) {
                                $day	 = strtolower($daywk);
                                $dayCode = $day . '_code';
                                
                                if($employeTpl){
                                    if ($planSemEmploye->$dayCode == XRules::EntreeSortie) {
                                        print('calcul heures prevues');
                                        $calculator	 = new \RHX\Model\Object\XCalculator($this->getAdapter());
                                        $prorata	 = $calculator->prorataHeurePrevues($employeTpl->heure_prevues, $day);

                                        /* Si l'employe template n'esiste pas heure_prevues = contrat hebdomadaire
                                         */
                                        
                                        if ($prorata['float'] < 0.0) {
                                            $planSemEmploye->heure_prevues = $employeTpl->heure_prevues;
                                        }
                                        else {
                                            $planSemEmploye->heure_prevues = $prorata['time'];
                                        }
                                    }
                                }
                                else{
                                    $avenant = $thisEmp->getAvenant();
                                    $contrat_hebdomadaire = $avenant->hebdo ;
                                    $planSemEmploye->heure_prevues = $contrat_hebdomadaire;
                                }
                            } // end foreach

                            print ("<span style='color: blue;'> heures prevus  " . $planSemEmploye->heure_prevues . '</span> <br>');
                            $planningSemaineTable->save($planSemEmploye);
                        }
                    }
                    // END  update prorata planning semaine
		}
	    }
	    else { // contrat est hors du periode : effacer les planning semaines de l' employe
		// Parcours des semaines de la période
		foreach ($semaineList as $semaine) {
		    $lundi = $semaine->lundi;

		    print('semaine ' . $semaine->id . '[  lundi : ' . $lundi . '] | ');
		    //$planningSemaine = $planningSemaineTable->getPlanningByEmploye($lundi, $employeMatrArray);

		    $planSemEmploye = $planningSemaineTable->getByEmploye($matricule, $lundi);
		    //$planSemEmploye = $planningSemaineTable->getPlanningByEmploye($lundi, array($matricule));

		    print($planSemEmploye ? 'ps ' . $planSemEmploye->id : 'ps vide '); // != null? $planSemEmploye->id : 'NOT') ;

		    if ($planSemEmploye) {
			print (' effacer ce planning semaine ' . $planSemEmploye->id . ' <br>');
			$planningSemaineTable->erase($planSemEmploye->id);
		    }
		    print('<br>');
		}
	    } // end if 
	}
	//die;

	return array();
    }
    
    /* mettre à jour le planning semaine d'un 
     * @param int $matricule 
     * @param RHX/Model/Object/PlanningSemaine $planning
     * @param int $templateId
     */
    public function updatePlanningSemaine($matricule, $planning , $templateId){ 
        //tables 
        $employeTable   = new \RHX\Model\Table\EmployeTable($this->getAdapter());
        $psTable        = new \RHX\Model\Table\PlanningSemaineTable($this->getAdapter());
                
        $employe = $employeTable->get($matricule);
        print(' -- CODE PS    -- { ');
        $dateEntree	 = new RHDateTime($employe->contrat_debut);
	$hasDateDepart	 = $employe->contrat_fin != null && $employe->contrat_fin !== '' && $employe->contrat_fin !== '0000-00-00';
	$dateDepart	 = $hasDateDepart ? new RHDateTime($employe->contrat_fin) : null;
        $dayWks			 = array('Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche');
        
        foreach ($dayWks as $daywkCap) {
            $dayWk = strtolower($daywkCap);

            $dayDate	 = 'date' . $daywkCap;
            $$dayDate	 = new RHDateTime($planning->$dayWk);
            $day_code	 = $dayWk . '_code';
            $dayEntree	 = $dayWk . '_entree';
            $daySortie	 = $dayWk . '_sortie';
            $dayPause	 = $dayWk . '_pause';
            $dayRepas	 = $dayWk . '_repas';

            if ($hasDateDepart) {
                $isJourInContrat = $$dayDate->isBetween($dateEntree, $dateDepart);
            }
            else {
                $isJourInContrat = $$dayDate->isGT($dateEntree) || $$dayDate->isEqual($dateEntree);
            }
            echo ($isJourInContrat ? 'IC    -' : 'HC - ');

            // //echo $planning->$day_code . ' <span style=\' font-size: 60%; color: blue;\'>PTE '. $employeTemplate->$day_code . '</span>' ;

            if (!$isJourInContrat) { // CAS (21) si jr hors contrat
                print(" <span style='background: #ffeeee;'> ToES </span>");
                $planning->$day_code	 = XRules::EntreeSortie;
                $planning->$dayEntree	 = '00:00';
                $planning->$daySortie	 = '00:00';
                $planning->$dayPause	 = 0;
                $planning->$dayRepas	 = 0;
                $psTable->save($planning);
            }
            else { // Dans la contrat 
                $notES = $planning->$day_code != XRules::EntreeSortie;
                if ($notES) { // CAS jour pas vièrge : laisser tel quel
                    print( '</span>' . "<span style='background: #eeeeff;'> telquel </span>");
                    // not modify
                }
                else { // modifier par { info PT || disponibilité }
                    $employeTemplateTable	 = new \RHX\Model\Table\EmployeTemplateTable($this->getAdapter());
                    $employeTemplate	 = $employeTemplateTable->getEmployeTemplate($matricule, $templateId);
                    
                    print( '</span>' . " <span style='background: #eeffee;'> ToPT " . $employeTemplate->$day_code . " </span>");

                    $planning->$day_code = $employeTemplate->$day_code;
                    $planning->$dayEntree	 = $employeTemplate->$dayEntree;
                    $planning->$daySortie	 = $employeTemplate->$daySortie;
                    $planning->$dayPause	 = $employeTemplate->$dayPause;
                    $planning->$dayRepas	 = $employeTemplate->$dayRepas;

                    $psTable->save($planning);
                }
            }
            print(' | ');
        }
        print('}');
    }
    
     /* crée planning semaine  pour un employé de donné
     * @param int $matricule 
     * @param RHX/Model/Object/PlanningSemaine $planning
     * @param int $templateId
     * @param int $semaineId
     */
    public function createPlanningSemaine($matricule, $planning , $templateId, $semaineId){
        //tables 
        $employeTemplateTable	 = new \RHX\Model\Table\EmployeTemplateTable($this->getAdapter());
        $employeTable   = new \RHX\Model\Table\EmployeTable($this->getAdapter());
        $semaineTable   = new \RHX\Model\Table\SemaineTable($this->getAdapter());
        $psTable        = new \RHX\Model\Table\PlanningSemaineTable($this->getAdapter());
        
        //objet
        $employe = $employeTable->get($matricule);
        $semaine = $semaineTable->get($semaineId);
        
        // calculateur
	$calculator = new \RHX\Model\Object\XCalculator($this->getAdapter());
        
        $dateEntree	 = new RHDateTime($employe->contrat_debut);
	$hasDateDepart	 = $employe->contrat_fin != null && $employe->contrat_fin !== '' && $employe->contrat_fin !== '0000-00-00';
	$dateDepart	 = $hasDateDepart ? new RHDateTime($employe->contrat_fin) : null;
        $dayWks			 = array('Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche');
        
        $employeTpl	 = $employeTemplateTable->getEmployeTemplate($matricule, $templateId);        
        $hasTpl = $employeTpl ? true : false;
        if ($hasTpl) {
            echo (" >  EMP HAS PT ");
            //$this->createPlanningSemaine();
            foreach ($dayWks as $i => $daywk) {
                $day = strtolower($daywk);

                $dayCode	 = $day . '_code';
                $dayEntree	 = $day . '_entree';
                $daySortie	 = $day . '_sortie';
                $dayPause	 = $day . '_pause';
                $dayRepas	 = $day . '_repas';

                $planning->$day	 = $semaine->$day;
                $jour		 = new RHDateTime($planning->$day);

                $isDayBetween = ($dateEntree->isLT($jour) || $dateEntree->isEqual($jour) ) && (!$hasDateDepart || ($dateDepart->isGT($jour) || $dateDepart->isEqual($jour) ) );
                print($isDayBetween ? ' ch ' : ' notch');

                if ($isDayBetween) {
                    //si jour est entre la date d'entrée et de sortie et si, éventuellement, pas de date de depart => CODE TEMPLATE</pre>";                               
                    $planning->$dayCode	 = $employeTpl->$dayCode;
                    $planning->$dayEntree	 = $employeTpl->$dayEntree;
                    $planning->$daySortie	 = $employeTpl->$daySortie;
                    $planning->$dayPause	 = $employeTpl->$dayPause;
                    $planning->$dayRepas	 = $employeTpl->$dayRepas;
                }
                else {
                    $planning->$dayCode	 = XRules::EntreeSortie;
                    $planning->$dayEntree	 = "00:00";
                    $planning->$daySortie	 = "00:00";
                    $planning->$dayPause	 = 0;
                    $planning->$dayRepas	 = 0;
                }
            }
            $planning->matricule	 = $matricule;
            $idNewPlanning		 = $psTable->save($planning);
        }
        else { // use Disponibilité
            echo (" >  EMP HASNT PT ");
            $dispo = $employe->getDisponibilite();

            foreach ($dayWks as $i => $daywk) {
                $day = strtolower($daywk);

                $dayCode	 = $day . '_code';
                $dayEntree	 = $day . '_entree';
                $daySortie	 = $day . '_sortie';
                $dayPause	 = $day . '_pause';
                $dayRepas	 = $day . '_repas';

                $planning->$day	 = $semaine->$day;
                $jour		 = new RHDateTime($planning->$day);

                $isDayBetween = ($dateEntree->isLT($jour) || $dateEntree->isEqual($jour) ) && (!$hasDateDepart || ($dateDepart->isGT($jour) || $dateDepart->isEqual($jour) ) );
                print($isDayBetween ? ' ch ' : ' notch');

                if ($isDayBetween) {
                    //si jour est entre la date d'entrée et de sortie et si, éventuellement, pas de date de depart => CODE TEMPLATE</pre>";                               
                    $planning->$dayCode	 = $dispo->$day;
                    $planning->$dayEntree	 = $dispo->$dayEntree;
                    $planning->$daySortie	 = $dispo->$daySortie;
                    $planning->$dayPause	 = $calculator->isPause($planning->$dayEntree, $planning->$daySortie);
                    $planning->$dayRepas	 = $calculator->isRepas($planning->$dayEntree, $planning->$daySortie);
                }
                else {
                    $planning->$dayCode	 = XRules::EntreeSortie;
                    $planning->$dayEntree	 = "00:00";
                    $planning->$daySortie	 = "00:00";
                    $planning->$dayPause	 = 0;
                    $planning->$dayRepas	 = 0;
                }
            }
            print('<br> creating PS <br>');
            $planning->matricule	 = $matricule;
            $idNewPlanning		 = $psTable->save($planning);
        }
    } 

    /**
     * Récupération des heures non-plannifiées par semaines
     * 
     * @param int $matricule
     * @param string $date
     * @return array
     */
    public function getHNP($matricule, $date) {
	$periode	 = $this->getPeriode($date);
	$plannings	 = $this->getEmployePlanningByPeriode($matricule, $periode);
	$hnp		 = array();
	$calculator	 = new XCalculator($this->getAdapter());
	$employe = $this->getEmploye($matricule);
	foreach ($plannings as $p) {
	    $hnp[] = $this->calculHNPWeek($p, $employe, $date, $calculator);
	}
	return $hnp;
    }

    public function calculHNPWeek(PlanningSemaine $planning, Employe $employe, $date, XCalculator $calculator = null) {
	$calculator	 = is_null($calculator) ? new XCalculator($this->getAdapter()) : $calculator;
	$weekStat	 = $calculator->calculateOneWeek($planning, NULL, $date);
	$heureTravaille	 = $weekStat['heureTravaille'];
	$hebdo		 = $employe->getHoraireHebdo(false, $planning->lundi);
	$stats		 = $this->getWeekStat($planning);
	$codes		 = $stats['codes'];
	$heuresPrevues	 = '00:00';
	$prevues = '00:00';
	if (isset($codes[XRules::EntreeSortie])) {
	    $dayName	 = array(1 => 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche');
	    $heurePrevues	 = $calculator->prorataHeurePrevues(RHDateTime::toTime($hebdo), $dayName[$codes[XRules::EntreeSortie]]);
	    $prevues	 = $heurePrevues['time'];
	}else {
	    //$heurePrevues = RHDateTime::toTime($hebdo);
	    $prevues = RHDateTime::toTime($hebdo);
	    //$heurePrevues = $autre;
	    //var_dump($hebdo);
	    //echo "<pre>Hebdo : $hebdo ($prevues)</pre>";
	}
//	$heureNonPlanifie	 = RHDateTime::diffHours($heurePrevues, $heureTravaille, false);
//	return RHDateTime::toFloat($heureNonPlanifie);
	$hnp = array('travaille' => 0.0, 'prevues' => 0.0, 'hnp' => 0.0);
	$hnp['travaille'] = RHDateTime::toFloat($heureTravaille);
	$hnp['prevues'] = RHDateTime::toFloat($prevues);
	$hnp['hnp'] = $hnp['travaille'] - $hnp['prevues'];
	//echo '<pre>' .$heureTravaille .' - ' .$heuresPrevues .'</pre>';
	return $hnp;
    }
    
    /**
     * Mise à jour de tous les plannings semaines
     * 
     * @return array
     */
    public function updateAllPlanningSemaine(){
        $periodes = $this->getPeriodesATester();
        $sites = $this->getAllSites();
        $msg = array();
        foreach($sites as $site){
            foreach($periodes as $periode){
                $msg[] = $this->updateOnePlanningSemaine($site, $periode);
            }
        }
        return $msg;
    }
    
    /**
     * Mise à jour des plannings semaine des employés du site
     * 
     * @param Site $site
     * @param Periode $periode
     * @return array
     */
    public function updateOnePlanningSemaine($site, $periode){
        $employes = $this->getEmployes($site);
        $msg = array();
        $tableEmploye = new EmployeTable($this->getAdapter());
        foreach($employes as $e){
            if(!$this->shouldBePresent($e, $periode)){
                $msg[] = 'Supression de #' .$e->matricule .' des planning semaine de la période ' .$periode->libelle .' (' .$this->removeFromPlanningSemaine($e, $periode) .' effacées)';
                $msg[] = 'Suppression de #' .$this->removeFromSiteList($e, $tableEmploye) .' de la liste des employés du site ' .$e->site_id;
            }else{
                $plannings = $this->getEmployePlannings($e, $periode);
                if(count($plannings) == 0){
                    // Créer les planning semaine de la période
                    $plannings = $this->addToPlanningSemainePeriode($e, $periode);
                    foreach($plannings as $planning){
                        $msg[] = 'Ajout de #' .$e->matricule .' dans les planning semaine de la periode ' .$periode->libelle .'(' .$planning->id .')';
                    }
                }else{
                    // Ne fais rien tout est à jour
                }
            }
        }
        return $msg;
    }
    
    public function verifyES(){
	//
    }
    
    /**
     * Récupération des périodes à tester
     * 
     * @return array
     */
    public function getPeriodesATester(){
        // periode en cours
        $tablePeriode = new PeriodeTable($this->getAdapter());
        $periodeEnCours = $tablePeriode->getPeriode(date('Y-m-d'));
        $periodeFutures = $tablePeriode->getPeriodeFutures($periodeEnCours);
        $periodeFutures = (!is_null($periodeFutures)) ? $periodeFutures : array($tablePeriode->getTheLastPeriode());
        return $periodeFutures;
    }
    
    /**
     * Tous les sites
     * 
     * @return \Zend\Db\ResultSet\ResultSet
     */
    public function getAllSites(){
        $tableSite = new SiteTable($this->getAdapter());
        return $tableSite->getAll();
    }
    
    /**
     * Détermine si un employé appartient encore à la période ou non
     * 
     * @param Employe $employe
     * @param Periode $periode
     * @return boolean
     */
    public function shouldBePresent($employe, $periode){
        $contratDebut = new RHDateTime($employe->contrat_debut);
        $contratFin = ($employe->contrat_fin != '0000-00-00') ? new RHDateTime($employe->contrat_fin) : new RHDateTime(((int)date('Y') + 10) .date('m-d'));
        $periodeDebut = new RHDateTime($periode->debut);
        $periodeFin = new RHDateTime($periode->fin);
        if($contratDebut->isLT($periodeFin)){
            if($contratFin->isLT($periodeDebut) || $contratFin->isEqual($periodeDebut)){
                return false;
            }
            return true;
        }else{
            return false;
        }
    }
    
    /**
     * Effacer un employé des plannings semaines de la période
     * 
     * @param Employe $employe
     * @param Periode $periode
     * @return int Resultat de la requete
     */
    public function removeFromPlanningSemaine($employe, $periode){
        $sql = "DELETE FROM rh_planning_semaine WHERE matricule = $employe->matricule AND lundi BETWEEN '$periode->debut' AND '$periode->fin'";
	//var_dump($sql);
        $result = $this->getAdapter()
                ->query($sql)
                ->execute();
        return $result->count();
    }
    
    /**
     * Mise a jour de la liste dans la liste des employés du site
     * 
     * @param Employe $employe
     * @param EmployeTable $tableEmploye
     * @return int
     */
    public function removeFromSiteList($employe, $tableEmploye = null){
        $tableEmploye = is_null($tableEmploye) ? new EmployeTable($this->getAdapter()) : $tableEmploye;
        $employe->actif = 0;
        return $tableEmploye->save($employe);
    }
    
    /**
     * Récupérer les employés du site
     * 
     * @param Site $site
     * @return \Zend\Db\ResultSet\ResultSet
     */
    public function getEmployes($site){
        $tableEmploye = new EmployeTable($this->getAdapter());
        return $tableEmploye->getEmployesBySiteEx2($site->id);
    }
    
    /**
     * Planning Semaine de l'employe durant la periode
     * 
     * @param Employe $employe
     * @param Periode $periode
     * @return array
     */
    public function getEmployePlannings($employe, $periode){
        $tablePlanning = new PlanningSemaineTable($this->getAdapter());
        $plannings = $tablePlanning->getPlanningByPeriode($periode, $employe->matricule);
        if($plannings->count() == 0){
            return array();
        }else{
            $array = array();
            foreach($plannings as $p){
                $array[] = $p;
            }
            return $array;
        }
    }
    
    /**
     * Ajouter un employé au planning semaine d'une période
     * 
     * @param Employe $employe
     * @param Periode $periode
     * @return array
     */
    public function addToPlanningSemainePeriode($employe, $periode){
        $tablePlanning = new PlanningSemaineTable($this->getAdapter());
        $semaines = $this->getSemaines($periode);
        $dispo = $employe->getDisponibilite();
        $dayName = array('lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche');
        $calculator = new XCalculator($this->getAdapter());
        $array = array();
        foreach($semaines as $s){
	    if(!$this->havePlanningSemaine($employe->site_id, $s->id)){
		continue;
	    }
            $planning = new PlanningSemaine($this->getAdapter());
            $planning->matricule = $employe->matricule;
            foreach($dayName as $day){
                $dayCode = $day .'_code';
                $dayEntree = $day .'_entree';
                $daySortie = $day .'_sortie';
                $dayPause = $day .'_pause';
                $dayRepas = $day .'_repas';
                $planning->$day = $s->$day;
                $planning->$dayCode = $dispo->$day;
                $planning->$dayEntree = $dispo->$dayEntree;
                $planning->$daySortie = $dispo->$daySortie;
                $planning->$dayPause = ($calculator->isPause($dispo->$dayEntree, $dispo->$daySortie)) ? 1 : 0;
                $planning->$dayRepas = ($calculator->isRepas($dispo->$dayEntree, $dispo->$daySortie)) ? 1 : 0;
            }
            $planning->id = $tablePlanning->save($planning);
            $array[] = $planning;
        }
        return $array;
    }
    
    /**
     * Semaines dans une periode
     * 
     * @param Periode $periode
     * @return array
     */
    public function getSemaines($periode){
        $tablePeriodeSemaine = new \RHX\Model\Table\PeriodeSemaineTable($this->getAdapter());
        $semaines = $tablePeriodeSemaine->getSemainesByPeriode($periode->id);
        return $semaines;
    }
    
    /**
     * Site
     * 
     * @param int $siteId
     * @return Site
     */
    public function getSite($siteId){
	$table = new SiteTable($this->getAdapter());
	return $table->get($siteId);
    }
    
    /**
     * Détermine si une semaine a déja un planning semaine
     * 
     * @param int $site
     * @param int $semaine
     * @return boolean
     */
    public function havePlanningSemaine($site, $semaine){
	$view= new \RHX\Model\View\PSPlanningView($this->getAdapter());
	$ps = $view->getPlanningByWeek($site, $semaine);
	return is_null($ps) ? FALSE : TRUE;
    }
}
